/**
 * 
 */
package Phase2;

import java.io.Serializable;

import org.junit.Assert;


/**
 * 
 * State for when a node has neither down nor up pointers
 * 
 * @author rpadilla
 *
 */
public class EmptyState implements NodeState, Serializable
{
	private static final long serialVersionUID = 1L;
	private static NodeState singleton;
	/**
	 * private constructor
	 */
	private EmptyState()
	{
		
	}
	/**
	 * returns a singleton for DownState
	 * @return a reference to the DownState singleton
	 * @pre none
	 * @post return reference to the DownState singleton
	 */
	public static NodeState getState()
	{
		if(singleton == null)
		{
			singleton = new EmptyState();
		}
		return singleton;
	}
	@Override
	public boolean lockState(Node callingNode, boolean rootAccess)
		throws InterruptedException 
	{	
		return callingNode.acquireAccessPriviledge(rootAccess);
	}
	
	/**
	 * @param callingNode - node to goRight() from
	 * @post return instance of NodeOrRange to goRight to
	 * @see Phase2.NodeState#goRight(Phase2.Node)
	 * @pre callingNode.state instanceOf(EmptyState)
	 */
	@Override
	public NodeOrRange goRight(Node callingNode, boolean rootAccess)  throws InterruptedException
	{		
		if(callingNode.getNeighbours(rootAccess).size() > 0)
		{
			callingNode.releaseAccessPriviledge();
			return callingNode.getNeighbours(rootAccess).getMax();
		}
		else
		{
			callingNode.releaseAccessPriviledge();
			return null;
		}
	}
	
	/**
	 * checks if the node's is correctly assigned an emptyState
	 * @param node checks this node
	 * @return whether it is in an emptyState or not
	 * @pre node != null, node is of the correct state
	 * @post return true if it is the correct state, otherwise false
	 */
	public boolean assertState(Node node) throws InterruptedException
	{
		boolean rootAccess = true;
		
		Assert.assertTrue(node != null);
		
		Assert.assertTrue(node.getDownPointers(rootAccess).size() == 0);
		
		Assert.assertTrue(node.getUpPointers(rootAccess).size() == 0);		
		
		return true;
	}
	
	/**
	 * Returns a string representation of the state
	 * @return "EmptyState"
	 * @pre None
	 * @post return "EmptyState"
	 */
	public String toString()
	{
		return "EmptyState";
	}

}
